package com.fiberhome.opticalbox.net;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import android.text.TextUtils;

import com.fiberhome.opticalbox.net.bean.Parameter;
import com.fiberhome.opticalbox.net.bean.RequestBean;
import com.fiberhome.opticalbox.net.bean.ResponseBean;
import com.fiberhome.opticalbox.utils.LogUtil;
import com.google.gson.Gson;

/**
 * @author wangpeng
 * @date 2014-12-24
 */
public class TcpMander {

	private String mServerAddress = "192.168.8.1"; // 218.80.254.215

	private int mTimeout = 8000;

	private int mServerPort = 17998;

	private boolean mUseBase64 = true;

	private ExecutorService executor = Executors.newSingleThreadExecutor();

	private OnTcpCommunicateListener mListener;

	public TcpMander(OnTcpCommunicateListener listener) {
		this.mListener = listener;
	}

	public TcpMander(String serverAddress, int timeout, int serverPort, OnTcpCommunicateListener listener) {
		this.mServerAddress = serverAddress;
		this.mTimeout = timeout;
		this.mServerPort = serverPort;
		this.mListener = listener;
	}

	class TcpSender implements Runnable {
		String request;

		public TcpSender(String request) {
			this.request = request;
		}

		@Override
		public void run() {
			String result = null;
			try {
				// LogUtils.d("result:" + request);
				result = TcpClient.sendAndReceiveTcpPacket(mServerAddress, mServerPort, request, mTimeout, mUseBase64);
			} catch (Exception e) {
				LogUtil.e(e.getMessage());
			}
			if (TextUtils.isEmpty(result)) {
				LogUtil.e("null result");
				mListener.onError(new Exception("null response"), "");
				// fix : 去知道哪条消息挂了
				LogUtil.d("to return fail response");
				Gson g = new Gson();
				RequestBean requestBean = g.fromJson(request, RequestBean.class);
				String cmdType = requestBean.getParameter().getCmdType();
				ResponseBean responseBean = new ResponseBean();
				responseBean.return_Parameter = new Parameter(cmdType , "");
				responseBean.return_Parameter.Status = "1";
				mListener.onComplete(responseBean);
			} else {
				Gson g = new Gson();
				mListener.onComplete(g.fromJson(result, ResponseBean.class));
			}
		}
	}

	public void sendTcp(byte[] str) {
		executor.execute(new TcpSender(new String(str)));
	}

	public void shutdownAndAwaitTermination() {
		executor.shutdown(); // Disable new tasks from being submitted
		try {
			// Wait a while for existing tasks to terminate
			if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
				executor.shutdownNow(); // Cancel currently executing tasks
				// Wait a while for tasks to respond to being cancelled
				if (!executor.awaitTermination(60, TimeUnit.SECONDS))
					System.err.println("Pool did not terminate");
			}
		} catch (InterruptedException ie) {
			// (Re-)Cancel if current thread also interrupted
			executor.shutdownNow();
			// Preserve interrupt status
			Thread.currentThread().interrupt();
		}
	}

	public void setTimeout(int timeout) {
		this.mTimeout = timeout;
	}

	public void setServerAddress(String serverAddress) {
		mServerAddress = serverAddress;
	}

	public void setServerPort(int serverPort) {
		mServerPort = serverPort;
	}

	public interface OnTcpCommunicateListener {

		public void onComplete(ResponseBean response, Object... args);

		public void onError(Exception exception, String sendStr);

	}

	public void setListener(OnTcpCommunicateListener listener) {
		mListener = listener;
	}

	public void setSocketParams(String localIp, int localPort) {
		mServerAddress = localIp;
		mServerPort = localPort;
	}

}
